package com.zero.manage.web.components.service.impl;

import com.zero.manage.web.components.base.BaseService;
import com.zero.manage.web.components.dao.SysRoleDao;
import com.zero.manage.web.components.dao.SysRolePowerDao;
import com.zero.manage.web.components.entity.rbac.*;
import com.zero.manage.web.components.query.SysRoleQuery;
import com.zero.manage.web.components.service.SysRoleService;
import io.gitee.zerowsh.enums.ToolEnums;
import io.gitee.zerowsh.config.Utils;
import io.gitee.zerowsh.util.PublicResult;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 系统角色 业务接口实现
 *
 * @author zero
 */
@Service
public class SysRoleServiceImpl extends BaseService<SysRoleEntity, String, SysRoleDao, SysRoleQuery> implements SysRoleService {
    private QSysRoleEntity qSysRoleEntity = QSysRoleEntity.sysRoleEntity;
    private QSysUserRoleEntity qSysUserRoleEntity = QSysUserRoleEntity.sysUserRoleEntity;
    private QSysRolePowerEntity qSysRolePowerEntity = QSysRolePowerEntity.sysRolePowerEntity;
    @Autowired
    private SysRolePowerDao sysRolePowerDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PublicResult updateState(String id, ToolEnums.StateEnums state) {
        jpa.update(qSysRoleEntity)
                .set(qSysRoleEntity.state, state)
                .set(qSysRoleEntity.updateTime, Utils.getCurrentTime())
                .where(qSysRoleEntity.id.eq(id))
                .execute();
        return PublicResult.updateOk();
    }

    @Override
    public PublicResult getIdAndName() {
        List<Map<String, Object>> collect = jpa.select(qSysRoleEntity.id, qSysRoleEntity.name, qSysRoleEntity.state)
                .from(qSysRoleEntity).fetch().stream()
                .map(tuple -> {
                    Map<String, Object> map = new HashMap<>(3);
                    map.put("id", tuple.get(qSysRoleEntity.id));
                    map.put("name", tuple.get(qSysRoleEntity.name));
                    map.put("state", tuple.get(qSysRoleEntity.state));
                    return map;
                }).collect(Collectors.toList());
        return PublicResult.queryOk(collect);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PublicResult deleteByIds(List<SysRoleEntity> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return PublicResult.delFail("参数不能为空");
        }
        //删除角色
        mapper.deleteInBatch(ids);
        //删除用户关联角色
        jpa.delete(qSysUserRoleEntity).where(qSysUserRoleEntity.roleId.in(ids.stream().map(SysRoleEntity::getId).collect(Collectors.toSet()))).execute();
        //删除角色关联权限
        jpa.delete(qSysRolePowerEntity).where(qSysRolePowerEntity.roleId.in(ids.stream().map(SysRoleEntity::getId).collect(Collectors.toSet()))).execute();
        return super.deleteByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PublicResult update(SysRoleEntity sysRoleEntity) {
        PublicResult publicResult = super.update(sysRoleEntity);
        // 删除角色关联权限
        jpa.delete(qSysRolePowerEntity).where(qSysRolePowerEntity.roleId.eq(sysRoleEntity.getId())).execute();
        addRolePowerInfo(sysRoleEntity);
        return publicResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PublicResult add(SysRoleEntity sysRoleEntity) {
        PublicResult publicResult = super.add(sysRoleEntity);
        addRolePowerInfo(sysRoleEntity);
        return publicResult;
    }

    public void addRolePowerInfo(SysRoleEntity sysRoleEntity) {
        Set<SysPowerEntity> powers = sysRoleEntity.getPowers();
        if (CollectionUtils.isNotEmpty(powers)) {
            for (SysPowerEntity power : powers) {
                SysRolePowerEntity sysRolePowerEntity = new SysRolePowerEntity();
                sysRolePowerEntity.setRoleId(sysRoleEntity.getId());
                sysRolePowerEntity.setPowerId(power.getId());
                sysRolePowerDao.save(sysRolePowerEntity);
            }
        }
    }
}
